package com.kfyang.manualgear.daoplugin.intention;

import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.navigation.NavigationUtil;
import com.intellij.codeInspection.util.IntentionFamilyName;
import com.intellij.codeInspection.util.IntentionName;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.kfyang.manualgear.daoplugin.Constants;
import org.jetbrains.annotations.NotNull;

public class GenerateYAMLIntention implements IntentionAction {

    @Override
    public @IntentionName @NotNull String getText() {
        return "[manual gear] generate yml";
    }

    @Override
    public @NotNull @IntentionFamilyName String getFamilyName() {
        return getText();
    }

    @Override
    public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile psiFile) {
        PsiElement element = psiFile.findElementAt(editor.getCaretModel().getOffset());
        PsiClass psiClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
        if (element != null && psiClass != null
            && psiClass.isInterface() && psiClass.hasAnnotation(Constants.DAO_ANNO)) {
            return true;
        }
        return false;
    }

    @Override
    public void invoke(@NotNull Project project, Editor editor, PsiFile psiFile) throws IncorrectOperationException {
        PsiElement element = psiFile.findElementAt(editor.getCaretModel().getOffset());
        PsiClass clazz = PsiTreeUtil.getParentOfType(element, PsiClass.class);

        VirtualFile baseDir = ProjectUtil.guessProjectDir(project);
        FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
        descriptor.setTitle("Select Target Folder");
        descriptor.setRoots(baseDir);
        VirtualFile virtualFile = FileChooser.chooseFile(descriptor, project, baseDir);
        if (virtualFile != null) {
            processGenerate(project, editor, clazz, PsiManager.getInstance(project).findDirectory(virtualFile));
        }
    }

    private void processGenerate(Project project, Editor editor, PsiClass clazz, PsiDirectory directory) {
        if (directory == null || !directory.isWritable()) {
            HintManager.getInstance().showErrorHint(editor, "Choose directory failed");
            return;
        }

        WriteCommandAction.runWriteCommandAction(project, () -> {
            PsiFile file = directory.createFile(clazz.getName() + ".yml");
            if (file != null) {
                Document document = PsiDocumentManager.getInstance(project).getDocument(file);
                String content = "namespace: " + clazz.getQualifiedName() + "\n";
                document.insertString(0, content);
                FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
                NavigationUtil.activateFileWithPsiElement(file, true);
                Editor targetEditor = fileEditorManager.getSelectedTextEditor();
                assert targetEditor != null;
                targetEditor.getCaretModel().moveToOffset(document.getTextLength());
                targetEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
            }
        });
    }

    @Override
    public boolean startInWriteAction() {
        return false;
    }
}
